home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / dkbtrace / pbmplus / source / pnm / tifftopn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-29  |  6.5 KB  |  277 lines

  1. /*
  2. ** tifftopnm.c - converts a Tagged Image File to a portable anymap
  3. **
  4. ** Derived by Jef Poskanzer from tif2ras.c, which is:
  5. **
  6. ** Copyright (c) 1990 by Sun Microsystems, Inc.
  7. **
  8. ** Author: Patrick J. Naughton
  9. ** naughton@wind.sun.com
  10. **
  11. ** Permission to use, copy, modify, and distribute this software and its
  12. ** documentation for any purpose and without fee is hereby granted,
  13. ** provided that the above copyright notice appear in all copies and that
  14. ** both that copyright notice and this permission notice appear in
  15. ** supporting documentation.
  16. **
  17. ** This file is provided AS IS with no warranties of any kind.  The author
  18. ** shall have no liability with respect to the infringement of copyrights,
  19. ** trade secrets or any patents by this file or any part thereof.  In no
  20. ** event will the author be liable for any lost revenue or profits or
  21. ** other special, indirect and consequential damages.
  22. */
  23.  
  24. #include "pnm.h"
  25. #include "tiffio.h"
  26.  
  27. #define MAXCOLORS 1024
  28.  
  29. void
  30. main( argc, argv )
  31.     int argc;
  32.     char* argv[];
  33.     {
  34.     int argn, cols, rows, grayscale, format;
  35.     int numcolors;
  36.     register TIFF* tif;
  37.     int row, i;
  38.     register int col;
  39.     unsigned char* buf;
  40.     register unsigned char* inP;
  41.     int maxval;
  42.     xel* xelrow;
  43.     register xel* xP;
  44.     xel colormap[MAXCOLORS];
  45.     int headerdump;
  46.     register unsigned char sample;
  47.     register int bitsleft;
  48.     unsigned short bps, spp, photomet;
  49.     unsigned short* redcolormap;
  50.     unsigned short* greencolormap;
  51.     unsigned short* bluecolormap;
  52.     char* usage = "[-headerdump] [tifffile]";
  53.  
  54.     pnm_init( &argc, argv );
  55.  
  56.     argn = 1;
  57.     headerdump = 0;
  58.  
  59.     if ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0' )
  60.     {
  61.     if ( pm_keymatch( argv[argn], "-headerdump", 2 ) )
  62.         headerdump = 1;
  63.     else
  64.         pm_usage( usage );
  65.     ++argn;
  66.     }
  67.  
  68.     if ( argn != argc )
  69.     {
  70.     tif = TIFFOpen( argv[argn], "r" );
  71.     if ( tif == NULL )
  72.         pm_error( "error opening TIFF file %s", argv[argn] );
  73.     ++argn;
  74.     }
  75.     else
  76.     {
  77.     tif = TIFFFdOpen( 0, "Standard Input", "r" );
  78.     if ( tif == NULL )
  79.         pm_error( "error opening standard input as TIFF file" );
  80.     }
  81.  
  82.     if ( argn != argc )
  83.     pm_usage( usage );
  84.  
  85.     if ( headerdump )
  86.     TIFFPrintDirectory( tif, stderr, TIFFPRINT_NONE );
  87.  
  88.     if ( ! TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bps ) )
  89.     bps = 1;
  90.     if ( ! TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &spp ) )
  91.     spp = 1;
  92.     if ( ! TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photomet ) )
  93.     pm_error( "error getting photometric" );
  94.  
  95.     switch ( spp )
  96.     {
  97.     case 1:
  98.     case 3:
  99.     case 4:
  100.     break;
  101.  
  102.     default:
  103.     pm_error(
  104.         "can only handle 1-channel gray scale or 1- or 3-channel color" );
  105.     }
  106.  
  107.     (void) TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &cols );
  108.     (void) TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &rows );
  109.  
  110.     if ( headerdump )
  111.     {
  112.     pm_message( "%dx%dx%d image", cols, rows, bps * spp );
  113.     pm_message( "%d bits/sample, %d samples/pixel", bps, spp );
  114.     }
  115.  
  116.     maxval = ( 1 << bps ) - 1;
  117.     if ( maxval == 1 && spp == 1 )
  118.     {
  119.     if ( headerdump )
  120.         pm_message("monochrome" );
  121.     grayscale = 1;
  122.     }
  123.     else
  124.     {
  125.     switch ( photomet )
  126.         {
  127.         case PHOTOMETRIC_MINISBLACK:
  128.         if ( headerdump )
  129.         pm_message( "%d graylevels (min=black)", maxval + 1 );
  130.         grayscale = 1;
  131.         break;
  132.  
  133.         case PHOTOMETRIC_MINISWHITE:
  134.         if ( headerdump )
  135.         pm_message( "%d graylevels (min=white)", maxval + 1 );
  136.         grayscale = 1;
  137.         break;
  138.  
  139.         case PHOTOMETRIC_PALETTE:
  140.         if ( headerdump )
  141.         pm_message( "colormapped" );
  142.         if ( ! TIFFGetField( tif, TIFFTAG_COLORMAP, &redcolormap, &greencolormap, &bluecolormap ) )
  143.         pm_error( "error getting colormaps" );
  144.         numcolors = maxval + 1;
  145.         if ( numcolors > MAXCOLORS )
  146.         pm_error( "too many colors" );
  147.         maxval = PNM_MAXMAXVAL;
  148.         grayscale = 0;
  149.         for ( i = 0; i < numcolors; ++i )
  150.         {
  151.         register xelval r, g, b;
  152.         r = (long) redcolormap[i] * PNM_MAXMAXVAL / 65535L;
  153.         g = (long) greencolormap[i] * PNM_MAXMAXVAL / 65535L;
  154.         b = (long) bluecolormap[i] * PNM_MAXMAXVAL / 65535L;
  155.         PPM_ASSIGN( colormap[i], r, g, b );
  156.         }
  157.         break;
  158.  
  159.         case PHOTOMETRIC_RGB:
  160.         if ( headerdump )
  161.         pm_message( "truecolor" );
  162.         grayscale = 0;
  163.         break;
  164.  
  165.         case PHOTOMETRIC_MASK:
  166.         pm_error( "don't know how to handle PHOTOMETRIC_MASK" );
  167.  
  168.         case PHOTOMETRIC_DEPTH:
  169.         pm_error( "don't know how to handle PHOTOMETRIC_DEPTH" );
  170.  
  171.         default:
  172.         pm_error( "unknown photometric: %d", photomet );
  173.         }
  174.     }
  175.     if ( maxval > PNM_MAXMAXVAL )
  176.     pm_error(
  177. "bits/sample is too large - try reconfiguring with PGM_BIGGRAYS\n    or without PPM_PACKCOLORS" );
  178.  
  179.  
  180.     if ( grayscale )
  181.     {
  182.     if ( maxval == 1 )
  183.         {
  184.         format = PBM_TYPE;
  185.         pm_message( "writing PBM file" );
  186.         }
  187.     else
  188.         {
  189.         format = PGM_TYPE;
  190.         pm_message( "writing PGM file" );
  191.         }
  192.     }
  193.     else
  194.     {
  195.     format = PPM_TYPE;
  196.     pm_message( "writing PPM file" );
  197.     }
  198.  
  199.     buf = (unsigned char*) malloc(TIFFScanlineSize(tif));
  200.     if ( buf == NULL )
  201.     pm_error( "can't allocate memory for scanline buffer" );
  202.     pnm_writepnminit( stdout, cols, rows, (xelval) maxval, format, 0 );
  203.     xelrow = pnm_allocrow( cols );
  204.  
  205. #define NEXTSAMPLE \
  206.     { \
  207.     if ( bitsleft == 0 ) \
  208.     { \
  209.     ++inP; \
  210.     bitsleft = 8; \
  211.     } \
  212.     bitsleft -= bps; \
  213.     sample = ( *inP >> bitsleft ) & maxval; \
  214.     }
  215.  
  216.     for ( row = 0; row < rows; ++row )
  217.     {
  218.     if ( TIFFReadScanline( tif, buf, row, 0 ) < 0 )
  219.         pm_error( "bad data read on line %d", row );
  220.     inP = buf;
  221.     bitsleft = 8;
  222.     xP = xelrow;
  223.  
  224.     switch ( photomet )
  225.         {
  226.         case PHOTOMETRIC_MINISBLACK:
  227.         for ( col = 0; col < cols; ++col, ++xP )
  228.         {
  229.         NEXTSAMPLE
  230.         PNM_ASSIGN1( *xP, sample );
  231.         }
  232.         break;
  233.  
  234.         case PHOTOMETRIC_MINISWHITE:
  235.         for ( col = 0; col < cols; ++col, ++xP )
  236.         {
  237.         NEXTSAMPLE
  238.         sample = maxval - sample;
  239.         PNM_ASSIGN1( *xP, sample );
  240.         }
  241.         break;
  242.  
  243.         case PHOTOMETRIC_PALETTE:
  244.         for ( col = 0; col < cols; ++col, ++xP )
  245.         {
  246.         NEXTSAMPLE
  247.         *xP = colormap[sample];
  248.         }
  249.         break;
  250.  
  251.         case PHOTOMETRIC_RGB:
  252.         for ( col = 0; col < cols; ++col, ++xP )
  253.         {
  254.         register xelval r, g, b;
  255.  
  256.         NEXTSAMPLE
  257.         r = sample;
  258.         NEXTSAMPLE
  259.         g = sample;
  260.         NEXTSAMPLE
  261.         b = sample;
  262.         if ( spp == 4 )
  263.             NEXTSAMPLE        /* skip alpha channel */
  264.         PPM_ASSIGN( *xP, r, g, b );
  265.         }
  266.         break;
  267.  
  268.         default:
  269.         pm_error( "unknown photometric: %d", photomet );
  270.         }
  271.     pnm_writepnmrow( stdout, xelrow, cols, (xelval) maxval, format, 0 );
  272.     }
  273.  
  274.     pm_close( stdout );
  275.     exit( 0 );
  276.     }
  277.